#include <iostream>
#include <string>

#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>

typedef websocketpp::server<websocketpp::config::asio> wsserver_t;

void wsopen_callback(wsserver_t *srv, websocketpp::connection_hdl hdl)
{
    std::cout << "websock握手成功!!\n";
}
void wsclose_callback(wsserver_t *srv, websocketpp::connection_hdl hdl)
{
    std::cout << "websock连接断开!!\n";
}

void print(const std::string str)
{
    std::cout<<str<<std::endl;
}
void http_callback(wsserver_t *srv, websocketpp::connection_hdl hdl)
{
    // 返回一个hello world的页面
    wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);
    std::cout << " body: " << conn->get_request_body() << std::endl;

    websocketpp::http::parser::request req = conn->get_request();
    std::cout << " method: " << req.get_method() << std::endl;
    std::cout << " uri: " << req.get_uri() << std::endl;

    std::string body = "<html><body><h1>hello world</h1></body></html>";
    conn->set_body(body); // 设置http响应正文
    conn->append_header("Content-Type", "text/html");
    conn->set_status(websocketpp::http::status_code::ok);

    srv->set_timer(1000,std::bind(print,"kangchu!!"));
}

void wsmsg_callback(wsserver_t *srv, websocketpp::connection_hdl hdl, wsserver_t::message_ptr msg)
{
    wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);

    std::cout << "wsmsg: " << msg->get_payload() << std::endl;
    std::string rsp = "Client say: " + msg->get_payload(); 
    conn->send(rsp, websocketpp::frame::opcode::text);
}

int main()
{
    // 1.实例化server对象
    wsserver_t wssrv;
    // 2.设置日志等级
    wssrv.set_access_channels(websocketpp::log::alevel::none); // 禁止打印所有日志
    // 3.初始化asio调度器
    wssrv.init_asio();
    wssrv.set_reuse_addr(true); // 设置地址重用
    // 4.设置回调函数
    wssrv.set_open_handler(std::bind(wsopen_callback, &wssrv, std::placeholders::_1));                          // websocket握⼿成功回调处理函数
    wssrv.set_close_handler(std::bind(wsclose_callback, &wssrv, std::placeholders::_1));                        // 断开连接回调处理函数
    wssrv.set_http_handler(std::bind(http_callback, &wssrv, std::placeholders::_1));                            // http请求回调处理函数
    wssrv.set_message_handler(std::bind(wsmsg_callback, &wssrv, std::placeholders::_1, std::placeholders::_2)); // 消息回调处理函数
    // 5.设置监听端口
    wssrv.listen(8085);
    // 6.开始获取新连接
    wssrv.start_accept();
    // 7.连接服务器
    wssrv.run();
    return 0;
}